package mysql

import (
	"errors"
	"fmt"
	"gitee.com/captials-team/ubdframe/src/domain/configstc"
	"gitee.com/captials-team/ubdframe/src/domain/dto"
	"gitee.com/captials-team/ubdframe/src/domain/dto/paginate"
	"gitee.com/captials-team/ubdframe/src/domain/interfaces"
	"gitee.com/captials-team/ubdframe/src/domain/models"
	mysqlClients "gitee.com/captials-team/ubdframe/src/infrastructure/clients/mysql"
	"gorm.io/gorm"
)

func NewStatisticalDao(conf configstc.DBConfig) *StatisticalDao {
	return &StatisticalDao{
		db:   mysqlClients.NewGormDB(conf),
		conf: conf,
	}
}

type StatisticalDao struct {
	db   *gorm.DB
	conf configstc.DBConfig
}

func (dao *StatisticalDao) Search(search *dto.SearchStatisticalParams, pa *paginate.Pager) ([]*models.Statistical, *paginate.Pager, error) {
	if search == nil {
		search = &dto.SearchStatisticalParams{}
	}
	if pa == nil {
		pa = &paginate.Pager{}
	}
	pa.Correct()

	db := dao.db.Model(new(models.Statistical))

	var list []*models.Statistical

	if search.Date != "" {
		db = db.Where("date=?", search.Date)
	}
	if search.Name != "" {
		db = db.Where("name=?", search.Name)
	}

	if ret := db.Count(&pa.Total); ret.Error != nil {
		return list, pa, ret.Error
	}

	db = db.Order("id desc")
	if ret := db.Limit(pa.Size).Offset(pa.Offset()).Find(&list); ret.Error != nil {
		return list, pa, ret.Error
	}
	return list, pa, nil
}

func (dao *StatisticalDao) Query(search *dto.SearchStatisticalParams) (*models.Statistical, error) {
	if search == nil {
		search = &dto.SearchStatisticalParams{}
	}
	var info models.Statistical

	db := dao.db.Model(&info).Order("id desc")
	if search.Date != "" {
		db = db.Where("date=?", search.Date)
	}
	if search.Name != "" {
		db = db.Where("name=?", search.Name)
	}
	ret := db.First(&info)
	if errors.Is(ret.Error, gorm.ErrRecordNotFound) {
		return nil, nil
	}
	if ret.Error != nil {
		return nil, ret.Error
	}
	return &info, nil
}

func (dao *StatisticalDao) Add(add *models.Statistical) (int64, error) {
	if add.Id > 0 {
		return 0, fmt.Errorf("not support update")
	}
	ret := dao.db.Model(add).Create(add)
	if ret.Error != nil {
		return 0, ret.Error
	}
	if ret.RowsAffected == 0 {
		return 0, fmt.Errorf("add fail")
	}

	return add.Id, nil
}

func (dao *StatisticalDao) Delete(id int64) (int64, error) {
	ret := dao.db.Where("id=?", id).Delete(&models.Statistical{})
	if ret.Error != nil {
		return 0, ret.Error
	}
	if ret.RowsAffected == 0 {
		return 0, fmt.Errorf("no delete")
	}
	return ret.RowsAffected, nil
}

func (dao *StatisticalDao) DeleteByName(name, date string) (int64, error) {
	ret := dao.db.Where("name=?", name).Where("date=?", date).Delete(&models.Statistical{})
	if ret.Error != nil {
		return 0, ret.Error
	}
	if ret.RowsAffected == 0 {
		return 0, fmt.Errorf("no delete")
	}
	return ret.RowsAffected, nil
}

func (dao *StatisticalDao) Migrate() (int64, error) {
	return 1, dao.db.AutoMigrate(new(models.Statistical))
}

func (dao *StatisticalDao) Use(db *gorm.DB) interfaces.ItfStatistical {
	return &StatisticalDao{db: db}
}

func (dao *StatisticalDao) DB() *gorm.DB {
	return dao.db
}
